function gewTerrainMaterial(effect,name)
{ 
  // general properties
  gewMaterial.call(this,effect,name);
  this.heightMap = null;
  this.textureMap = null;
  this.alphaMap = null;
  this.materialTex0 = null;
  this.materialTex1 = null;
  this.materialTex2 = null;
  this.materialTex3 = null;
  this.terrainSize = 1024;
  //this.minHeight = 0.;
  //this.maxHeight = 100.;
  this.materialSize = 8;
  this.materialBlendFactor = [0.3,0.3,0.3,0.3];
  this.materialBlendRadius = 400.;
  this.updateStep = 32;
  this.diffuse = new gewVec3(1,1,1);
  this.ambient = new gewVec3(1,1,1);
  //Private: 
  this.isNeedUpdate = true;//
  this.currentTranslateX = 0;
  this.currentTranslateZ = 0;
  this.shaderTranslateX = 0;
  this.shaderTranslateZ = 0;  
}
//gewTerrainMaterial.prototype = new gewMaterial();
extend2(gewTerrainMaterial,gewMaterial);
gewTerrainMaterial.prototype.update = function(scene3d)
{
  if(this.isNeedUpdate)
  {
    var list  = this.nodeList;
    var listLen = list.length; 
    var viewPos = scene3d.viewPosition;
    var step = this.updateStep;
    var vx = viewPos.x;
    var vz = viewPos.z;
    var tx = this.currentTranslateX;
    var tz = this.currentTranslateZ;
    var isNeedUpdateHeight = false;
    var deltaX = tx-vx;
    var deltaZ = tz-vz;
    
    if( Math.abs(deltaX)>step || 
        Math.abs(deltaZ)>step)
        isNeedUpdateHeight = true;
    if(isNeedUpdateHeight) 
    {
      this.currentTranslateX = vx;
      if( deltaX>0)
        tx = Math.floor(vx);
      else
        tx = Math.floor(vx);
      this.shaderTranslateX = tx;
      this.currentTranslateZ = vz;
      if(deltaZ>0)
        tz = (Math.floor(vz));
      else
        tz = (Math.floor(vz));
      this.shaderTranslateZ = tz;
      
      for (var i = 0; i < listLen; i++) 
        list[i].updateHeight(this.heightMap,tx,tz);
    }
  }
  this.isNeedUpdate = false;
}
gewTerrainMaterial.prototype.render = function()
{
  //this.updateBatches();
  this.isRendering = true;
  // Render node list
  var heightMap = this.heightMap;
  var textureMap = this.textureMap
  var alphaMap = this.alphaMap;
  var effect = this.effect;
  var shader = effect.shader;
  var scene3d = effect.scene3d;
  var gl = this.gl;
  if(heightMap&&heightMap.isReady)
  {  
    gl.uniform1i(shader.textureMap, 0);
    gl.activeTexture(gl.TEXTURE0);
    gl.bindTexture(gl.TEXTURE_2D, textureMap.glName);
    
    gl.uniform1i(shader.alphaMap,1);
    gl.activeTexture(gl.TEXTURE1);
    gl.bindTexture(gl.TEXTURE_2D, alphaMap.glName);
    
    gl.uniform1i(shader.materialTex0,2)
    gl.activeTexture(gl.TEXTURE2);
    gl.bindTexture(gl.TEXTURE_2D, this.materialTex0.glName);
    
    gl.uniform1i(shader.materialTex1,3)
    gl.activeTexture(gl.TEXTURE3);
    gl.bindTexture(gl.TEXTURE_2D, this.materialTex1.glName);
    
    gl.uniform1i(shader.materialTex2,4)
    gl.activeTexture(gl.TEXTURE4);
    gl.bindTexture(gl.TEXTURE_2D, this.materialTex2.glName);
    
    gl.uniform1i(shader.materialTex3,5)
    gl.activeTexture(gl.TEXTURE5);
    gl.bindTexture(gl.TEXTURE_2D, this.materialTex3.glName);
    
    gl.uniform1i(shader.shadowMap,6)
    gl.activeTexture(gl.TEXTURE6);
    gl.bindTexture(gl.TEXTURE_2D, scene3d.shadowMap);
    
    gl.uniform3f(shader.ambient, this.ambient.x,this.ambient.y,this.ambient.z);
    gl.uniform3f(shader.diffuse, this.diffuse.x,this.diffuse.y,this.diffuse.z);
    
    var list  = this.nodeList;
    var listLen = list.length;   
    
    this.update(scene3d);
    this.isNeedUpdate = true;
    gl.uniform3f(shader.translateToWorld, this.shaderTranslateX, 0, this.shaderTranslateZ );
    //var fogDensity = scene3d.fog.density;
    //var negFogDensitySquareMulLog2 = -fogDensity*fogDensity*1.442695;    
    gl.uniform3f(shader.vertexParam, this.terrainSize,this.materialBlendRadius,this.materialSize);
    var blendF = this.materialBlendFactor;
    gl.uniform4f(shader.materialBlendFactor, blendF[0],blendF[1],blendF[2],blendF[3]);
    gl.uniform2f(shader.fragmentParam, scene3d.mainLight.lightData[9], (1.0/scene3d.shadowMapWidth)*0.51 );
    var viewProjMat = scene3d.viewProjectMat;
    gl.uniformMatrix4fv(shader.viewProjectionMat, false, viewProjMat.data);
    for (var i = 0; i < listLen; i++) 
    {
      var node = list[i];
      //var modelMat = node.modelMat.data;
      if(!node.isVisible)
        continue;
      node.setAttributePointers(this);
      node.render(this);
    }
  }
  this.isRendering = false;
}
